import re
import ast

# 改进的注释移除逻辑：仅移除字符串外部的分号注释
def remove_comments(line):
    in_double = False
    in_single = False
    escaped = False
    for i, c in enumerate(line):
        if escaped:
            escaped = False
            continue
        if c == '\\':
            escaped = True
        elif c == '"' and not in_single:
            in_double = not in_double
        elif c == '\'' and not in_double:
            in_single = not in_single
        elif c == ';' and not in_double and not in_single:
            return line[:i]
    return line

def tokenize(text):
    # 按行处理注释移除并保留行结构
    lines = text.split('\n')
    result = []  # 存储最终结果的双重列表
    
    # 遍历每行，跟踪行号（从1开始）
    for line_number, original_line in enumerate(lines, start=1):
        # 移除行注释
        processed_line = remove_comments(original_line)
        
        # 定义令牌匹配模式，按优先级排序
        pattern = r'''
            ("[^"\\]*(?:\\.[^"\\]*)*")      # 字符串字面量
          | (\'[^\'\\]*(?:\\.[^\'\\]*)*\')  # 字符字面量
          | (0x[0-9a-fA-F]+|0b[01]+|\d+)    # 数字
          | ([a-zA-Z_][a-zA-Z0-9_]*:)       # label
          | ([a-zA-Z_][a-zA-Z0-9_]*)        # 标识符
          | (\[.*?\])                       # []值
          | (\s+)                           # 空白字符
          | (.+)                            # 未知字符串
        '''
        
        line_tokens = []
        # 遍历当前行的所有匹配令牌
        for match in re.findall(pattern, processed_line, re.VERBOSE):
            if match[0]:  # 字符串处理
                try:
                    value = ast.literal_eval(match[0])
                    line_tokens.append(('string', value))
                except SyntaxError:
                    pass
            elif match[1]:  # 字符处理
                try:
                    value = ast.literal_eval(match[1])
                    line_tokens.append(('char', value))
                except SyntaxError:
                    pass
            elif match[2]:  # 数字处理
                num_str = match[2]
                try:
                    if num_str.startswith('0x'):
                        value = int(num_str, 16)
                    elif num_str.startswith('0b'):
                        value = int(num_str, 2)
                    else:
                        value = int(num_str, 10)
                    line_tokens.append(('number', value))
                except ValueError:
                    pass
            elif match[3]:  # label处理
                label_name = match[3][:-1]  # 移除末尾冒号
                line_tokens.append(('label', label_name))
            elif match[4]:  # 标识符处理
                line_tokens.append(('id', match[4]))
            elif match[5]:  # []值处理
                content = match[5][1:-1].strip()
                line_tokens.append(('bracket', content))
            # 忽略空白字符
            elif match[7]:  # 未知字符处理
                line_tokens.append(('unknown', match[7]))

        # 如果行中有tokens，则添加到结果中（过滤无效行）
        if line_tokens:
            result.append([line_number, *line_tokens])
    
    return result
